﻿#region Disclaimer/Info
///////////////////////////////////////////////////////////////////////////////////////////////////
// MetaCollection
// 
// MetaCollection is a system to provide a standard structure, permissions and metadata service
// for content organization.
//
// This project is hosted at Google Code at http://code.google.com/p/metacollection/
//
// This project is licensed under the BSD license.  See the License.txt file for more information.
///////////////////////////////////////////////////////////////////////////////////////////////////
#endregion

using System;
using System.Collections.Generic;
using System.IO;
using MetaCollection.Framework;
using MetaCollection.Framework.Model;
using System.Text;
using System.Web;
using System.Linq;
using MetaCollection.ContentService.WebDav;
using MetaCollection.Framework.Security;

namespace MetaCollection.ContentService.Template
{

	public class TemplateLoader : NDjango.Interfaces.ITemplateLoader
	{
		/// <summary>
		/// reference to an item request handler for loading database templates.
		/// </summary>
		IRequestHandler m_handler;
		MetaPrincipal m_User;

		public  TemplateLoader()
		{
		}


		private IRequestHandler ItemHandler
		{
			get
			{
				if (m_handler == null) { m_handler = RequestHandlerFactory.CreateRequestHandler(); } return m_handler;
			}
		}

		private MetaPrincipal User
		{
			get
			{
				if (m_User == null) { m_User = HttpContext.Current.User as MetaPrincipal; } return m_User;
			}
		}
		/// <summary>
		/// Gets the template by either a direct referece, a file uri or a collection uri.
		/// </summary>
		/// <param name="path">The template path.</param>
		/// <returns>a text reader opened and reading on a template.</returns>
		public TextReader GetTemplate(string path)
		{
			Uri templateUri;

			if (Uri.TryCreate(path, UriKind.Absolute, out templateUri))
			{
				if (templateUri.Scheme == Uri.UriSchemeFile)
					return File.OpenText(Uri.UnescapeDataString(templateUri.LocalPath));
				else if (templateUri.Scheme.Equals("col://", StringComparison.OrdinalIgnoreCase))
					return new StreamReader(ItemHandler.ResourceRequest(User, RequestTypes.GetResource, templateUri, null));
			}
			return new StringReader(path);
		}

		/// <summary>
		/// Determines whether the specified source is updated.
		/// </summary>
		/// <param name="path">The source path.</param>
		/// <param name="timestamp">The time stamp.</param>
		/// <returns>
		/// 	<c>true</c> if the specified source is updated; otherwise, <c>false</c>.
		/// </returns>
		/// <remarks>
		/// It is safe to always return false here because the source is the actual template string.  
		/// If the template is modified, the source will be different. Therefore NDjango will believe we have a new template.
		/// </remarks>
		[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes", Justification="While this type of catching does make a black hole of sorts, the Load Template method will have the same issues.  If the load method was previously successful but there is a failure in here then something changed so returning true is the correct behavior.")]
		public bool IsUpdated(string path, DateTime timestamp)
		{
			Uri templateUri;
			try
			{
				if (Uri.TryCreate(path, UriKind.Absolute, out templateUri))
				{
					if (templateUri.Scheme == Uri.UriSchemeFile)
						return File.GetLastWriteTime(templateUri.AbsolutePath) > timestamp;
					else if (templateUri.Scheme.Equals("col://", StringComparison.OrdinalIgnoreCase))
					{
						IItemInstance templateItem =  ItemHandler.ItemRequest(User, RequestTypes.GetItem,templateUri).FirstOrDefault();
						return ((templateItem != null) && (templateItem.LastModified > timestamp));
					}
				}
				return false; // this is not a template uri so it is either a raw template or a default (non-uri) template.
			}
			catch
			{
				return true; // there was an issue reading the path as a file uri or getting the path as a collection uri.  In either case our template we have is not current.
			}
		}	
			
	}
}
